package com.dingding.order.core.publish.biz.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.http.HttpStatus;
import org.apache.log4j.Logger;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

import com.dingding.common.core.base.code.BaseCodeMessage;
import com.dingding.common.core.base.dto.ResponseEntity;
import com.dingding.common.core.beans.UserCoupon;
import com.dingding.common.core.beans.UserTaxiOrdert;
import com.dingding.common.core.util.DateFormatUtil;
import com.dingding.common.core.util.GetDistanceUtil;
import com.dingding.common.core.util.ToolUtil;
import com.dingding.common.core.util.dto.CalculatDistanceDTO;
import com.dingding.common.core.util.paravalidate.ValiResult;
import com.dingding.common.core.util.paravalidate.ValidateUtil;
import com.dingding.facade.queue.facade.IQueueFacade;
import com.dingding.facade.user.facade.passanger.coupon.IUserCouponFacade;
import com.dingding.order.core.publish.biz.IPublishOrderByTaxiService;
import com.dingding.order.core.publish.dao.IPublishTaxiOrderDao;
import com.dingding.order.dto.publish.taxi.PublishTaxiOrderStatus;
import com.dingding.order.dto.publish.taxi.ReqPublishOrderByTaxi;
import com.dingding.order.dto.publish.taxi.ResPublishOrderByTaxi;

/**
 * 
 * @ClassName: PublishOrderByTaxiServiceImpl
 * @Description: 发布出租车订单Service实现
 * @author YHQ
 * @date 2016年11月21日 下午5:07:01
 * @since V2.5.6
 * 
 */
@Component("publishOrderByTaxiService")
public class PublishOrderByTaxiServiceImpl implements IPublishOrderByTaxiService {

	private Logger log = Logger.getLogger(this.getClass());

	@Resource(name = "publishTaxiOrderDao")
	private IPublishTaxiOrderDao publishTaxiOrderDao;

	@Resource(name = "queueFacade")
	private IQueueFacade queueFacade;

	@Resource(name = "_userCouponFacade")
	private IUserCouponFacade userCouponFacade;

	/**
	 * 
	 * @Title: publishOrderByTaxi
	 * @Description: 发布出租车订单
	 * @param requestData
	 *            客户端请求参数
	 * @author YHQ
	 * @return ResponseEntity<ResPublishOrderByTaxi> 返回类型
	 * 
	 */
	@Override
	public ResponseEntity<ResPublishOrderByTaxi> publishOrderByTaxi(ReqPublishOrderByTaxi reqPublishOrderByTaxi) {

		// 确认上车响应Bean
		ResponseEntity<ResPublishOrderByTaxi> response = new ResponseEntity<ResPublishOrderByTaxi>();

		// 验证参数是否为空
		boolean flag = this.validateParamAndCondition(response, reqPublishOrderByTaxi);

		if (!flag) {
			return response;
		}

		// 补充发布出租车订单请求参数
		completionParam(reqPublishOrderByTaxi);

		// 判断乘客是否存在未完成的出租车单,如果有未完成的出租车单则不能发单
		if (this.publishTaxiOrderDao.haveUnfinishedTaxiOrder(reqPublishOrderByTaxi.getPlaceOrderUserId())) {
			response.setCode(PublishTaxiOrderStatus.HAVE_UN_FINISHED_TAXI_ORDER.getCode());
			response.setErrorMessage(PublishTaxiOrderStatus.HAVE_UN_FINISHED_TAXI_ORDER.getMessage());
			response.setPromptMessage(PublishTaxiOrderStatus.HAVE_UN_FINISHED_TAXI_ORDER.getMessage());
			return response;
		}

		// 乘客下单
		UserTaxiOrdert order = this.generateCustomerTaxiOrder(reqPublishOrderByTaxi, response);
		if (order == null) {
			return response;
		}

		// 推送订单给附近的司机
		this.queueFacade.addTaxiOrderToQueue(order);

		// 封装返回结果
		ResPublishOrderByTaxi resPublishOrderByTaxi = createResult(order);
		response.setResponseBody(resPublishOrderByTaxi);
 
		return response;
	}

	/**
	 * 
	 * @Title: validateParam
	 * @param response
	 *            发布出租车订单响应Bean
	 * @param reqConfirmAboardDTO
	 *            发布出租车订单请求Bean
	 * @author YHQ
	 * @since V2.5.6
	 * @return boolean 返回类型
	 * 
	 */
	public boolean validateParamAndCondition(ResponseEntity<ResPublishOrderByTaxi> response,
			ReqPublishOrderByTaxi reqPublishOrderByTaxi) {

		// 判断客户端请求数据是否为空
		ValiResult valiResult = ValidateUtil.validateBeanIsAvaliable(reqPublishOrderByTaxi,
				ReqPublishOrderByTaxi.class);

		if (!valiResult.isAvailable()) {
			response.setCode(HttpStatus.SC_FORBIDDEN);
			response.setErrorMessage(BaseCodeMessage.DATA_NULL_PARAM_MESSAGE);
			response.setPromptMessage(BaseCodeMessage.HTTP_REQUEST_ERROR);
			response.setNullProperties(valiResult.getNullFieldName());
			log.error("为空字段为：" + valiResult.getNullFieldName());
			return false;
		}

		return true;
	}

	/**
	 * 
	 * @Title: completionParam
	 * @Description: 补全发布出租车订单请求参数
	 * @param reqPublishTaixOrder
	 * @author YHQ
	 * @since V2.5.6
	 * @return ReqPublishTaixOrder 返回类型
	 * 
	 */
	public ReqPublishOrderByTaxi completionParam(ReqPublishOrderByTaxi reqPublishOrderByTaxi) {

		// 计算里程与获取城市
		CalculatDistanceDTO calculatDistanceDTO = GetDistanceUtil.getSingleDistance(
				reqPublishOrderByTaxi.getStartLongitude(), reqPublishOrderByTaxi.getStartLatitude(),
				reqPublishOrderByTaxi.getEndLongitude(), reqPublishOrderByTaxi.getEndLatitude());

		if (reqPublishOrderByTaxi == null || calculatDistanceDTO == null) {
			return null;
		}

		// 下单城市
		if (ToolUtil.isBlank(reqPublishOrderByTaxi.getPayCity())) {
			reqPublishOrderByTaxi.setPayCity(calculatDistanceDTO.getCityName());
		}

		// 人数
		if (reqPublishOrderByTaxi.getNumber() == null) {
			reqPublishOrderByTaxi.setNumber(0);
		}

		// 距离
		if (reqPublishOrderByTaxi.getDistance() == null) {
			reqPublishOrderByTaxi.setDistance(calculatDistanceDTO.getDistance());
		}

		return reqPublishOrderByTaxi;
	}

	/**
	 * @Description:生成乘客订单
	 * @author fengshuonan
	 * @return int 状态码
	 */
	private UserTaxiOrdert generateCustomerTaxiOrder(ReqPublishOrderByTaxi reqPublishOrderByTaxi,
			ResponseEntity<ResPublishOrderByTaxi> response) {

		UserTaxiOrdert userTaxiOrdert = new UserTaxiOrdert();

		// 拷贝请求bean中的所有属性，除了payCity下单城市，因为userTaxiOrdert中属性为placeOrderCity
		BeanUtils.copyProperties(reqPublishOrderByTaxi, userTaxiOrdert);

		// 生成订单id
		userTaxiOrdert.setTaxiOrdertId(ToolUtil.getUid());

		// 设置下单城市
		userTaxiOrdert.setPlaceOrderCity(reqPublishOrderByTaxi.getPayCity());

		// 设置出发时间为当前服务器时间
		userTaxiOrdert.setSetOutTime(new Date());

		// 设置下单时间
		userTaxiOrdert.setCreateTime(new Date());

		// 设置下单类型（1:司机下单 2:乘客下单）
		userTaxiOrdert.setOrderType(2);

		// 设置订单状态
		userTaxiOrdert.setOrderStatus(1);

//		UserCoupon userCoupon = getUserCoupon(reqPublishOrderByTaxi.getPlaceOrderUserId(),
//				reqPublishOrderByTaxi.getPayCity());
//	    if(userCoupon !=null){
//	    	
//	    	//优惠金额
//			userTaxiOrdert.setCouponMoney(userCoupon.getCouponMoney());
//			// 优惠券ID
//			userTaxiOrdert.setCouponId(userCoupon.getCouponId());
//	    	
//	    }
		
		try {
			this.publishTaxiOrderDao.save(userTaxiOrdert);
			return userTaxiOrdert;
		} catch (Exception e) {
			log.error("出租车下单生成订单出错！PublishTaxiOrderServiceImpl : generateCustomerTaxiOrder()", e);
			response.setCode(PublishTaxiOrderStatus.GENERATE_TAXI_ORDER_ERROR.getCode());
			response.setErrorMessage(PublishTaxiOrderStatus.GENERATE_TAXI_ORDER_ERROR.getMessage());
			return null;
		}
	}

	/**
	 * 
	 * @Description: 获取用户优惠券
	 * @param userId
	 * @param cityNo
	 * @author CHEHUANBO
	 * @version V2.6.2
	 * 
	 */
	private UserCoupon getUserCoupon(String userId, String cityNo) {

		Map<String, Object> reqMap = new HashMap<String, Object>();
		reqMap.put("userId", userId);
		reqMap.put("produceType", 2);
		reqMap.put("cityNo", cityNo);

		UserCoupon userCoupon = null;

		try {
			Map<String, Object> resMap = userCouponFacade.getUserCoupon(reqMap);
			userCoupon = (UserCoupon) resMap.get("userCoupon");
		} catch (Exception e) {
			log.info("出租车发单远程调用获取用户优惠券出现异常！", e);
		}

		return userCoupon;

	}

	/**
	 * @Description: 封装发布出租车订单结果bean
	 * @author fengshuonan
	 * @return ResPublishTaixOrder 发布出租车订单的响应bean
	 * 
	 */
	private ResPublishOrderByTaxi createResult(UserTaxiOrdert order) {

		// 创建返回结果的封装
		ResPublishOrderByTaxi resPublishOrderByTaxi = new ResPublishOrderByTaxi();

		// 设置订单id
		resPublishOrderByTaxi.setOid(order.getTaxiOrdertId());
		// 设置出发时间(标准格式)
		resPublishOrderByTaxi.setOutTime(DateFormatUtil.getMMddEHHss(order.getSetOutTime()));
		// 订单里程
		resPublishOrderByTaxi.setDistance(order.getDistance());
		// 发单类型
		resPublishOrderByTaxi.setPublishType(order.getOrderType());
		// 出发时间
		resPublishOrderByTaxi.setSetOutTime(order.getSetOutTime());
		// 下单时间
		resPublishOrderByTaxi.setCreatTime(order.getCreateTime());

		return resPublishOrderByTaxi;
	}

}
